package client_service

/**
* @author aFun
* @data 2025/4/12 12:33
* @email: afunaaa222@163.com / 1030935903
* @address: Guangdong University of Technology, China
 */

import (
	"camp_lucky_draw/entity"
	"camp_lucky_draw/transfer"
	"encoding/json"
	"errors"
	"fmt"
	"github.com/patrickmn/go-cache"
	"net"
	"slices"
	"strconv"
	"sync"
	"time"
)

type UserProcess struct{}
type CurUser_ struct {
	Conn net.Conn
	Role *entity.Role
}

var CurUser CurUser_

// 创建一个全局的map[channel]，用于读取不同协议的响应
var RespChannelMap = make(map[int64]chan *entity.Msg)
var RespChannelMapLock sync.Mutex

// 全局本地缓存
var globalCache = cache.New(10*time.Minute, 15*time.Minute)

// 和服务器保持通讯
func ServerProcessMes(Conn net.Conn) {
	// Request - Response 为不同的协议创建相应的管道
	Codes := []int64{
		10000, // 服务端主动推送数据
		10001, // 进入游戏世界协议
		10002, // 退出游戏世界协议
		27100, // 请求个人信息协议
		27101, // 请求层奖励信息协议
		27102, // 请求累计奖励信息协议
		27103, // 扭蛋协议
		27104, // 层奖励领取协议
		27105, // 累计奖励领取协议
	}
	//// 服务器主动推送的协议
	//PushCodes := []int64{
	//	27106, // 本地缓存 层奖励信息失效
	//	27107, // 本地缓存 累计奖励信息失败
	//	27200, // 扭蛋信息增量协议
	//  27201, // 背包物品增量更新
	//}

	for _, code := range Codes {
		RespChannelMap[code] = make(chan *entity.Msg)
	}

	tf := &transfer.Transfer{
		Conn: Conn,
	}

	for {
		//fmt.Println("client waiting.")
		mes, err := tf.ReadPkg()
		if err != nil {
			//fmt.Println("read pkg error:", err)
			return
		}

		if mes.Code == 27106 {
			cacheKey := fmt.Sprintf("floor_rewawrds_user_%d", CurUser.Role.ID)
			globalCache.Delete(cacheKey)
			//fmt.Println("本地缓存失效:", cacheKey)
		}

		if mes.Code == 27107 {
			cacheKey := fmt.Sprintf("cumulative_rewawrds_user_%d", CurUser.Role.ID)
			globalCache.Delete(cacheKey)
			//fmt.Println("本地缓存失效:", cacheKey)
		}

		if mes.Code == 27200 {
			// 活动数据增量协议
			ld := entity.LuckyDraw{}
			err := json.Unmarshal([]byte(mes.Repsonse_data), &ld)
			if err != nil {
				//fmt.Println("增量数据反序列化失败")
			}
			CurUser.Role.Lucky_draw = ld
			//fmt.Println("接收到扭蛋信息增量更新数据，本地数据更新成功")
		}

		if mes.Code == 27201 {
			// 背包物品增量协议
			itemQ := entity.ItemForQueue{}
			err := json.Unmarshal([]byte(mes.Repsonse_data), &itemQ)
			if err != nil {
				//fmt.Println("增量数据反序列化失败")
			}
			OldBags := CurUser.Role.Bags
			getItem := entity.Item{
				Id:   itemQ.Id,
				Name: itemQ.Name,
				Num:  itemQ.Num,
			}
			CurUser.Role.Bags = append(OldBags, getItem)
			//fmt.Println("收到物品：", getItem)
			//fmt.Println("原背包物品：", OldBags)
			//fmt.Println("现背包物品：", CurUser.Role.Bags)
		}

		// 分发消息
		if slices.Contains(Codes, mes.Code) {
			go func(m *entity.Msg) {
				RespChannelMapLock.Lock()
				defer RespChannelMapLock.Unlock()
				respChan, ok := RespChannelMap[m.Code]
				if ok {
					respChan <- m
				} else {
					//fmt.Println("消息未匹配到相应的协议：", m)
				}
			}(mes)
		}

	}
}

func (this *UserProcess) Enter_world(userId uint, showMenu bool) (err error) {
	CurConn, err := net.Dial("tcp", "localhost:8889")
	if err != nil {
		return errors.New("Dial err")
	}
	//defer CurConn.Close()
	var mes entity.Msg
	mes.Code = 10001
	mes.Request_data = strconv.Itoa(int(userId))
	data, err := json.Marshal(mes)
	if err != nil {
		return errors.New("marshal err")
	}
	tf := &transfer.Transfer{
		Conn: CurConn,
	}
	err = tf.WritePkg(data)
	if err != nil {
		return errors.New("write err")
	}
	respMsg, err := tf.ReadPkg()
	if err != nil {
		return errors.New("read pkg error")
	}
	if !respMsg.Status {
		return errors.New("respStatus: false")
	} else {
		//fmt.Println(respMsg.Repsonse_data)
		RespRole := &entity.Role{}
		err := json.Unmarshal([]byte(respMsg.Repsonse_data), &RespRole)
		if err != nil {
			return errors.New("unmarshal err")
		}
		CurUser.Role = RespRole
		CurUser.Conn = CurConn
		//fmt.Printf("roleId=%d 上号成功！\n", RespRole.ID)

		go ServerProcessMes(CurConn)
		if showMenu {
			ShowMenu()
		}
	}
	return nil
}
